//-------------------------------------------------------------------------------//
//                         QUIMERA ENGINE : LICENSE                              //
//-------------------------------------------------------------------------------//
// This file is part of Quimera Engine.                                          //
// Quimera Engine is free software: you can redistribute it and/or modify        //
// it under the terms of the Lesser GNU General Public License as published by   //
// the Free Software Foundation, either version 3 of the License, or             //
// (at your option) any later version.                                           //
//                                                                               //
// Quimera Engine is distributed in the hope that it will be useful,             //
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
// Lesser GNU General Public License for more details.                           //
//                                                                               //
// You should have received a copy of the Lesser GNU General Public License      //
// along with Quimera Engine. If not, see <http://www.gnu.org/licenses/>.        //
//                                                                               //
// This license doesn't force you to put any kind of banner or logo telling      //
// that you are using Quimera Engine in your project but we would appreciate     //
// if you do so or, at least, if you let us know about that.                     //
//                                                                               //
// Enjoy!                                                                        //
//                                                                               //
// Kinesis Team                                                                  //
//-------------------------------------------------------------------------------//

#ifndef __DELEGATEINTERNALS__
#define __DELEGATEINTERNALS__

#include "CommonDefinitions.h"

#include <cstring>

namespace Kinesis
{
namespace QuimeraEngine
{
namespace Common
{
namespace Internals
{

// ---------------------------------------------------------------------------------------------------------
// ABOUT THIS CODE
// The following code is an adaptation of the original code written by Don Clugston on April 6th 2005, at
// codeproject.com (http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible).
// It has been cleaned to get rid of those parts that are not useful for us and has been also re-indented.
// Several names have been changed too, in order to fulfill our conventions.
// However, many of the original explanatory comments have been left since nobody can explain the code better
// than its author (and they are very good explanations, indeed).
// ---------------------------------------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
//                        Compiler identification for workarounds
//
////////////////////////////////////////////////////////////////////////////////

// Does the compiler uses Microsoft's member function pointer structure?
// If so, it needs special treatment.
// Metrowerks CodeWarrior, Intel, and CodePlay fraudulently define Microsoft's
// identifier, _MSC_VER. We need to filter Metrowerks out.
#ifdef QE_COMPILER_MSVC
    #define QE_COMMON_DELEGATE_INTERNALS_MICROSOFT_MFP
    #define QE_COMMON_DELEGATE_INTERNALS_HASINHERITANCE_KEYWORDS
#elif defined(QE_COMPILER_GCC)  // Workaround GCC bug #8271
    // At present, GCC doesn't recognize constness of MFPs in templates
    #define QE_COMMON_DELEGATE_INTERNALS_GCC_BUG_8271
#endif



////////////////////////////////////////////////////////////////////////////////
//                        General tricks used in this code
//
// (a) Error messages are generated by typdefing an array of negative size to
//     generate compile-time errors.
// (b) Warning messages on MSVC are generated by declaring unused variables, and
//        enabling the "variable XXX is never used" warning.
// (c) Unions are used in a few compiler-specific cases to perform illegal casts.
// (d) For Microsoft and Intel, when adjusting the 'this' pointer, it's cast to
//     (char *) first to ensure that the correct number of *bytes* are added.
//
////////////////////////////////////////////////////////////////////////////////
//                        Helper templates
//
////////////////////////////////////////////////////////////////////////////////

//        ImplicitCast< >
// I believe this was originally going to be in the C++ standard but
// was left out by accident. It's even milder than static_cast.
// I use it instead of static_cast<> to emphasize that I'm not doing
// anything nasty.
// Usage is identical to static_cast<>
template <class OutputClassT, class InputClassT>
inline OutputClassT ImplicitCast(InputClassT input)
{
    // IMPORTANT: If you get a compilation ERROR that brings you directly here, check that you are not trying to
    // bind the delegate to a non-constant method of a constant object, which is not allowed.
    // KNOWN LIMITATIONS: If the class has 2 method overloads, one of them being constant, it is not possible
    // to recognize the constant overload at the moment. The non-constant overload will be used always.
    return input;
}


//        HorribleCast< >
// This is truly evil. It completely subverts C++'s type system, allowing you
// to cast from any class to any other class. Technically, using a union
// to perform the cast is undefined behaviour (even in C). But we can see if
// it is OK by checking that the union is the same size as each of its members.
// HorribleCast<> should only be used for compiler-specific workarounds.
// Usage is identical to reinterpret_cast<>.

// This union is declared outside the HorribleCast because BCC 5.5.1
// can't inline a function with a nested class, and gives a warning.
template <class OutputClassT, class InputClassT>
union HorribleUnion
{
    OutputClassT out;
    InputClassT in;
};

template <class OutputClassT, class InputClassT>
inline OutputClassT HorribleCast(const InputClassT input)
{
    HorribleUnion<OutputClassT, InputClassT> u;
    // Cause a compile-time error if in, out and u are not the same size.
    // If the compile fails here, it means the compiler has peculiar
    // unions which would prevent the cast from working.
    typedef int ERROR_CantUseHorrible_cast[sizeof(InputClassT)==sizeof(u)
        && sizeof(InputClassT)==sizeof(OutputClassT) ? 1 : -1];
    u.in = input;
    return u.out;
}

////////////////////////////////////////////////////////////////////////////////
//                        Workarounds
//
////////////////////////////////////////////////////////////////////////////////

// On any other compiler, just use a normal void.
typedef void DefaultVoid;

// Translate from 'DefaultVoid' to 'void'.
// Everything else is unchanged
template <class T>
struct DefaultVoidToVoid
{
    typedef T type;
};

template <>
struct DefaultVoidToVoid<DefaultVoid>
{
    typedef void type;
};

// Translate from 'void' into 'DefaultVoid'
// Everything else is unchanged
template <class T>
struct VoidToDefaultVoid
{
    typedef T type;
};

template <>
struct VoidToDefaultVoid<void>
{
    typedef DefaultVoid type;
};



////////////////////////////////////////////////////////////////////////////////
//                        Fast Delegates, part 1:
//
//        Conversion of member function pointer to a standard form
//
////////////////////////////////////////////////////////////////////////////////

// GenericClass is a fake class, ONLY used to provide a type.
// It is vitally important that it is never defined, so that the compiler doesn't
// think it can optimize the invocation. For example, Borland generates simpler
// code if it knows the class only uses single inheritance.

// Compilers using Microsoft's structure need to be treated as a special case.
#ifdef  QE_COMMON_DELEGATE_INTERNALS_MICROSOFT_MFP

#ifdef QE_COMMON_DELEGATE_INTERNALS_HASINHERITANCE_KEYWORDS
    // For Microsoft and Intel, we want to ensure that it's the most efficient type of MFP
    // (4 bytes), even when the /vmg option is used. Declaring an empty class
    // would give 16 byte pointers in this case....
    class __single_inheritance GenericClass;
#endif
    // ...but for Codeplay, an empty class *always* gives 4 byte pointers.
    // If compiled with the /clr option ("managed C++"), the JIT compiler thinks
    // it needs to load GenericClass before it can call any of its functions,
    // (compiles OK but crashes at runtime!), so we need to declare an
    // empty class to make it happy.
    // Codeplay and VC4 can't cope with the unknown_inheritance case either.
    class GenericClass
    {
    };
#else
    class GenericClass;
#endif

// The size of a single inheritance member function pointer.
const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (GenericClass::*)());

//                        SimplifyMemFunc< >::Convert()
//
//    A template function that converts an arbitrary member function pointer into the
//    simplest possible form of member function pointer, using a supplied 'this' pointer.
//  According to the standard, this can be done legally with reinterpret_cast<>.
//    For (non-standard) compilers which use member function pointers which vary in size
//  depending on the class, we need to use    knowledge of the internal structure of a
//  member function pointer, as used by the compiler. Template specialization is used
//  to distinguish between the sizes. Because some compilers don't support partial
//    template specialisation, I use full specialisation of a wrapper struct.

// general case -- don't know how to convert it. Force a compile failure
template <int N>
struct SimplifyMemFunc
{
    template <class X, class XFuncTypeT, class GenericMemFuncTTypeT>
    inline static GenericClass *Convert(X *pthis, XFuncTypeT function_to_bind,
                                        GenericMemFuncTTypeT &bound_func)
    {
        // Unsupported member function type -- force a compile failure.
        // (it's illegal to have a array with negative size).
        typedef char ERROR_Unsupported_member_function_pointer_on_this_compiler[N-100];
        return 0;
    }
};

// For compilers where all member func ptrs are the same size, everything goes here.
// For non-standard compilers, only single_inheritance classes go here.
template <>
struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE>
{
    template <class X, class XFuncTypeT, class GenericMemFuncTTypeT>
    inline static GenericClass *Convert(X *pthis, XFuncTypeT function_to_bind,
                                        GenericMemFuncTTypeT &bound_func)
    {

        bound_func = reinterpret_cast<GenericMemFuncTTypeT>(function_to_bind);

        return reinterpret_cast<GenericClass *>(pthis);
    }
};

////////////////////////////////////////////////////////////////////////////////
//                        Fast Delegates, part 1b:
//
//                    Workarounds for Microsoft and Intel
//
////////////////////////////////////////////////////////////////////////////////


// Compilers with member function pointers which violate the standard (MSVC, Intel, Codeplay),
// need to be treated as a special case.
#ifdef QE_COMMON_DELEGATE_INTERNALS_MICROSOFT_MFP

// We use unions to perform HorribleCasts. I would like to use #pragma pack(push, 1)
// at the start of each function for extra safety, but VC6 seems to ICE
// intermittently if you do this inside a template.

// __multiple_inheritance classes go here
// Nasty hack for Microsoft and Intel (IA32 and Itanium)
template<>
struct SimplifyMemFunc< SINGLE_MEMFUNCPTR_SIZE + sizeof(int) >
{
    template <class X, class XFuncTypeT, class GenericMemFuncTTypeT>
    inline static GenericClass *Convert(X *pthis, XFuncTypeT function_to_bind,
                                        GenericMemFuncTTypeT &bound_func)
    {
        // We need to use a HorribleCast to do this conversion.
        // In MSVC, a multiple inheritance member pointer is internally defined as:
        union
        {
            XFuncTypeT func;

            struct
            {
                GenericMemFuncTTypeT funcaddress; // points to the actual member function
                int delta;         // #BYTES to be added to the 'this' pointer
            } s;
        } u;

        // Check that the HorribleCast will work
        typedef int ERROR_CantUseHorribleCast[sizeof(function_to_bind) == sizeof(u.s) ? 1 : -1];
        u.func = function_to_bind;
        bound_func = u.s.funcaddress;
        return reinterpret_cast<GenericClass *>(reinterpret_cast<char *>(pthis) + u.s.delta);
    }
};

// virtual inheritance is a real nuisance. It's inefficient and complicated.
// On MSVC and Intel, there isn't enough information in the pointer itself to
// enable conversion to a closure pointer. Earlier versions of this code didn't
// work for all cases, and generated a compile-time error instead.
// But a very clever hack invented by John M. Dlugosz solves this problem.
// My code is somewhat different to his: I have no asm code, and I make no
// assumptions about the calling convention that is used.

// In VC++ and ICL, a virtual_inheritance member pointer
// is internally defined as:
struct MicrosoftVirtualMFP
{
    void (GenericClass::*codeptr)(); // points to the actual member function
    int delta;        // #bytes to be added to the 'this' pointer
    int vtable_index; // or 0 if no virtual inheritance
};

// The CRUCIAL feature of Microsoft/Intel MFPs which we exploit is that the
// m_codeptr member is *always* called, regardless of the values of the other
// members. (This is *not* true for other compilers, eg GCC, which obtain the
// function address from the vtable if a virtual function is being called).
// Dlugosz's trick is to make the codeptr point to a probe function which
// returns the 'this' pointer that was used.

// Define a generic class that uses virtual inheritance.
// It has a trival member function that returns the value of the 'this' pointer.
struct GenericVirtualClass : virtual public GenericClass
{
    typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)();

    GenericVirtualClass * GetThis()
    {
        return this;
    }
};

// __virtual_inheritance classes go here
template <>
struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 2 * sizeof(int) >
{

    template <class X, class XFuncTypeT, class GenericMemFuncTTypeT>
    inline static GenericClass *Convert(X *pthis, XFuncTypeT function_to_bind,
                                        GenericMemFuncTTypeT &bound_func)
    {
        union
        {
            XFuncTypeT func;
            GenericClass* (X::*ProbeFunc)();
            MicrosoftVirtualMFP s;
        } u;

        u.func = function_to_bind;
        bound_func = reinterpret_cast<GenericMemFuncTTypeT>(u.s.codeptr);

        union
        {
            GenericVirtualClass::ProbePtrType virtfunc;
            MicrosoftVirtualMFP s;
        } u2;

        // Check that the HorribleCast<>s will work
        typedef int ERROR_CantUseHorribleCast[sizeof(function_to_bind)==sizeof(u.s)
            && sizeof(function_to_bind)==sizeof(u.ProbeFunc)
            && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1];

        // Unfortunately, taking the address of a MF prevents it from being inlined, so
        // this next line can't be completely optimised away by the compiler.
        u2.virtfunc = &GenericVirtualClass::GetThis;
        u.s.codeptr = u2.s.codeptr;
        return (pthis->*u.ProbeFunc)();
    }
};

// Nasty hack for Microsoft and Intel (IA32 and Itanium)
// unknown_inheritance classes go here
// This is probably the ugliest bit of code I've ever written. Look at the casts!
// There is a compiler bug in MSVC6 which prevents it from using this code.
template <>
struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 3 * sizeof(int) >
{
    template <class X, class XFuncTypeT, class GenericMemFuncTTypeT>
    inline static GenericClass *Convert(X *pthis, XFuncTypeT function_to_bind,
                                        GenericMemFuncTTypeT &bound_func)
    {
        // The member function pointer is 16 bytes long. We can't use a normal cast, but
        // we can use a union to do the conversion.
        union
        {
            XFuncTypeT func;
            // In VC++ and ICL, an unknown_inheritance member pointer
            // is internally defined as:
            struct
            {
                GenericMemFuncTTypeT m_funcaddress; // points to the actual member function
                int delta;            // #bytes to be added to the 'this' pointer
                int vtordisp;        // #bytes to add to 'this' to find the vtable
                int vtable_index;   // or 0 if no virtual inheritance
            } s;
        } u;

        // Check that the HorribleCast will work
        typedef int ERROR_CantUseHorribleCast[sizeof(XFuncTypeT)==sizeof(u.s)? 1 : -1];
        u.func = function_to_bind;
        bound_func = u.s.funcaddress;
        int virtual_delta = 0;
        if (u.s.vtable_index) // Virtual inheritance is used
        {
            // First, get to the vtable.
            // It is 'vtordisp' bytes from the start of the class.
            const int * vtable = *reinterpret_cast<const int *const*>(
                reinterpret_cast<const char *>(pthis) + u.s.vtordisp );

            // 'vtable_index' tells us where in the table we should be looking.
            virtual_delta = u.s.vtordisp + *reinterpret_cast<const int *>(
                reinterpret_cast<const char *>(vtable) + u.s.vtable_index);
        }

        // The int at 'virtual_delta' gives us the amount to add to 'this'.
        // Finally we can add the three components together. Phew!
        return reinterpret_cast<GenericClass *>(
            reinterpret_cast<char *>(pthis) + u.s.delta + virtual_delta);
    };
};

#endif // MS/Intel hacks


////////////////////////////////////////////////////////////////////////////////
//                        Fast Delegates, part 2:
//
//    Define the delegate storage, and cope with static functions
//
////////////////////////////////////////////////////////////////////////////////

// DelegateData -- an opaque structure which can hold an arbitary delegate.
// It knows nothing about the calling convention or number of arguments used by
// the function pointed to.
// It supplies comparison operators so that it can be stored in STL collections.
// It cannot be set to anything other than null, nor invoked directly:
//   it must be converted to a specific delegate.

// Implementation:
// There are two possible implementations: the Safe method and the Evil method.
//                DelegateData - Safe version
//
// This implementation is standard-compliant, but a bit tricky.
// A static function pointer is stored inside the class.
// Here are the valid values:
// +-- Static pointer --+--pThis --+-- pMemFunc-+-- Meaning------+
// |   0                |  0       |   0        | Empty          |
// |   !=0              |(dontcare)|  Invoker   | Static function|
// |   0                |  !=0     |  !=0*      | Method call    |
// +--------------------+----------+------------+----------------+
//  * For Metrowerks, this can be 0. (first virtual function in a
//       single_inheritance class).
// When stored stored inside a specific delegate, the 'dontcare' entries are replaced
// with a reference to the delegate itself. This complicates the = and == operators
// for the delegate class.

//                DelegateData - Evil version
//
// For compilers where data pointers are at least as big as code pointers, it is
// possible to store the function pointer in the this pointer, using another
// HorribleCast. In this case the DelegateData implementation is simple:
// +--pThis --+-- pMemFunc-+-- Meaning---------------------+
// |    0     |  0         | Empty                         |
// |  !=0     |  !=0*      | Static function or method call|
// +----------+------------+-------------------------------+
//  * For Metrowerks, this can be 0. (first virtual function in a
//       single_inheritance class).
// Note that the Sun C++ and MSVC documentation explicitly state that they
// support static_cast between void * and function pointers.

class DelegateData
{

protected:
    // the data is protected, not private, because many
    // compilers have problems with template friends.
    typedef void (GenericClass::*GenericMemFuncTTypeT)(); // arbitrary MFP.
    GenericClass *m_pthis;
    GenericMemFuncTTypeT m_pFunction;

public:

    DelegateData() : m_pthis(0),
                     m_pFunction(0)
    {
    }

    void clear()
    {
        m_pthis=0;
        m_pFunction=0;
    }

public:


    inline bool IsEqual (const DelegateData &x) const
    {
        return m_pthis==x.m_pthis && m_pFunction==x.m_pFunction;
    }

    // Provide a strict weak ordering for DelegateDatas.
    inline bool IsLess(const DelegateData &right) const
    {
        // deal with static function pointers first

        if (m_pthis !=right.m_pthis)
            return m_pthis < right.m_pthis;

        // There are no ordering operators for member function pointers,
        // but we can fake one by comparing each byte. The resulting ordering is
        // arbitrary (and compiler-dependent), but it permits storage in ordered STL containers.
        return memcmp(&m_pFunction, &right.m_pFunction, sizeof(m_pFunction)) < 0;

    }
    // BUGFIX (Mar 2005):
    // We can't just compare m_pFunction because on Metrowerks,
    // m_pFunction can be zero even if the delegate is not empty!
    inline bool operator ! () const        // Is it bound to anything?
    {
        return m_pthis==0 && m_pFunction==0;
    }

    inline bool empty() const        // Is it bound to anything?
    {
        return m_pthis==0 && m_pFunction==0;
    }

public:

    DelegateData & operator = (const DelegateData &right)
    {
        SetDataFrom(right);
        return *this;
    }

    inline bool operator <(const DelegateData &right)
    {
        return IsLess(right);
    }

    inline bool operator >(const DelegateData &right)
    {
        return right.IsLess(*this);
    }

    DelegateData (const DelegateData &right)  : m_pthis(right.m_pthis),
                                                m_pFunction(right.m_pFunction)

    {
    }

protected:

    void SetDataFrom(const DelegateData &right)
    {
        m_pFunction = right.m_pFunction;
        m_pthis = right.m_pthis;
    }
};


//                        ClosurePtr<>
//
// A private wrapper class that adds function signatures to DelegateData.
// It's the class that does most of the actual work.
// The signatures are specified by:
// GenericMemFuncT: must be a type of GenericClass member function pointer.
// StaticFuncPtrT:  must be a type of function pointer with the same signature
//                 as GenericMemFuncT.
// UnvoidStaticFuncPtrT: is the same as StaticFuncPtrT, except on VC6
//                 where it never returns void (returns DefaultVoid instead).

// An outer class, FastDelegateN<>, handles the invoking and creates the
// necessary typedefs.
// This class does everything else.

template < class GenericMemFuncT, class StaticFuncPtrT, class UnvoidStaticFuncPtrT>
class ClosurePtr : public DelegateData
{
public:
    // These functions are for setting the delegate to a member function.

    // Here's the clever bit: we convert an arbitrary member function into a
    // standard form. XMemFuncT should be a member function of class X, but I can't
    // enforce that here. It needs to be enforced by the wrapper class.
    template < class X, class XMemFuncT >
    inline void bindmemfunc(X *pthis, XMemFuncT function_to_bind )
    {
        m_pthis = SimplifyMemFunc< sizeof(function_to_bind) >::Convert(pthis, function_to_bind, m_pFunction);
    }

    // For const member functions, we only need a const class pointer.
    // Since we know that the member function is const, it's safe to
    // remove the const qualifier from the 'this' pointer with a const_cast.
    // VC6 has problems if we just overload 'bindmemfunc', so we give it a different name.
    template < class X, class XMemFuncT>
    inline void bindconstmemfunc(const X *pthis, XMemFuncT function_to_bind)
    {
        m_pthis= SimplifyMemFunc< sizeof(function_to_bind) >::Convert(const_cast<X*>(pthis), function_to_bind, m_pFunction);
    }

#ifdef QE_COMMON_DELEGATE_INTERNALS_GCC_BUG_8271    // At present, GCC doesn't recognize constness of MFPs in templates
    template < class X, class XMemFuncT>
    inline void bindmemfunc(const X *pthis, XMemFuncT function_to_bind)
    {
        bindconstmemfunc(pthis, function_to_bind);
    }
#endif

    // These functions are required for invoking the stored function
    inline GenericClass* GetClosureThis() const
    {
        return m_pthis;
    }

    inline GenericMemFuncT GetClosureMemPtr() const
    {
        return reinterpret_cast<GenericMemFuncT>(m_pFunction);
    }

// There are a few ways of dealing with static function pointers.
// There's a standard-compliant, but tricky method.
// There's also a straightforward hack, that won't work on DOS compilers using the
// medium memory model. It's so evil that I can't recommend it, but I've
// implemented it anyway because it produces very nice asm code.

//                ClosurePtr<> - Evil version
//
// For compilers where data pointers are at least as big as code pointers, it is
// possible to store the function pointer in the this pointer, using another
// HorribleCast. Invocation isn't any faster, but it saves 4 bytes, and
// speeds up comparison and assignment. If C++ provided direct language support
// for delegates, they would produce asm code that was almost identical to this.
// Note that the Sun C++ and MSVC documentation explicitly state that they
// support static_cast between void * and function pointers.

    template< class DerivedClassT >
    inline void CopyFrom (DerivedClassT *pParent, const DelegateData &right)
    {
        SetDataFrom(right);
    }

    // For static functions, the 'static_function_invoker' class in the parent
    // will be called. The parent then needs to call GetStaticFunction() to find out
    // the actual function to invoke.
    // ******** EVIL, EVIL CODE! *******
    template <     class DerivedClassT, class ParentInvokerSigT>
    inline void bindstaticfunc(DerivedClassT *pParent, ParentInvokerSigT static_function_invoker,
                               StaticFuncPtrT function_to_bind)
    {
        if (function_to_bind == 0) // cope with assignment to 0
        {
            m_pFunction = 0;
        }
        else
        {
           // We'll be ignoring the 'this' pointer, but we need to make sure we pass
           // a valid value to bindmemfunc().
            bindmemfunc(pParent, static_function_invoker);
        }

        // WARNING! Evil hack. We store the function in the 'this' pointer!
        // Ensure that there's a compilation failure if function pointers
        // and data pointers have different sizes.
        // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK.
        typedef int ERROR_CantUseEvilMethod[sizeof(GenericClass *)==sizeof(function_to_bind) ? 1 : -1];
        m_pthis = HorribleCast< GenericClass* >(function_to_bind);
        // MSVC, SunC++ and DMC accept the following (non-standard) code:
//        m_pthis = static_cast<GenericClass *>(static_cast<void *>(function_to_bind));
        // BCC32, Comeau and DMC accept this method. MSVC7.1 needs __int64 instead of long
//        m_pthis = reinterpret_cast<GenericClass *>(reinterpret_cast<long>(function_to_bind));
    }

    // ******** EVIL, EVIL CODE! *******
    // This function will be called with an invalid 'this' pointer!!
    // We're just returning the 'this' pointer, converted into
    // a function pointer!
    inline UnvoidStaticFuncPtrT GetStaticFunction() const
    {
        // Ensure that there's a compilation failure if function pointers
        // and data pointers have different sizes.
        // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK.
        typedef int ERROR_CantUseEvilMethod[sizeof(UnvoidStaticFuncPtrT)==sizeof(this) ? 1 : -1];
        return HorribleCast<UnvoidStaticFuncPtrT>(this);
    }

    // Does the closure contain this static function?
    inline bool IsEqualToStaticFuncPtrT(StaticFuncPtrT funcptr)
    {
        if (funcptr==0)
            return empty();

        // For the Evil method, if it doesn't actually contain a static function, this will return an arbitrary
        // value that is not equal to any valid function pointer.
        else
            return funcptr == reinterpret_cast<StaticFuncPtrT>(GetStaticFunction());
    }
};


////////////////////////////////////////////////////////////////////////////////
//                        Fast Delegates, part 3:
//
//                Wrapper classes to ensure type safety
//
////////////////////////////////////////////////////////////////////////////////


// Once we have the member function conversion templates, it's easy to make the
// wrapper classes. So that they will work with as many compilers as possible,
// the classes are of the form
//   FastDelegate3<int, char *, double>
// They can cope with any combination of parameters. The max number of parameters
// allowed is 8, but it is trivial to increase this limit.
// Note that we need to treat const member functions seperately.
// All this class does is to enforce type safety, and invoke the delegate with
// the correct list of parameters.

// Because of the weird rule about the class of derived member function pointers,
// you sometimes need to apply a downcast to the 'this' pointer.
// This is the reason for the use of "ImplicitCast<X*>(pthis)" in the code below.
// If CDerivedClassT is derived from CBaseClass, but doesn't override SimpleVirtualFunction,
// without this trick you'd need to write:
//        MyDelegate(static_cast<CBaseClass *>(&d), &CDerivedClassT::SimpleVirtualFunction);
// but with the trick you can write
//        MyDelegate(&d, &CDerivedClassT::SimpleVirtualFunction);

// ReturnValueT is the type the compiler uses in compiling the template. For VC6,
// it cannot be void. DesiredReturnValueT is the real type which is returned from
// all of the functions. It can be void.

// Implicit conversion to "bool" is achieved using the safe_bool idiom,
// using member data pointers (MDP). This allows "if (dg)..." syntax
// Because some compilers (eg codeplay) don't have a unique value for a zero
// MDP, an extra padding member is added to the SafeBool struct.
// Some compilers (eg VC6) won't implicitly convert from 0 to an MDP, so
// in that case the static function constructor is not made explicit; this
// allows "if (dg==0) ..." to compile.

//N=0
template<class ReturnValueT = DefaultVoid>
class FastDelegate0
{
public:

    typedef typename DefaultVoidToVoid<ReturnValueT>::type DesiredReturnValueT;
    typedef DesiredReturnValueT (*StaticFunctionPtr)();
    typedef ReturnValueT (*UnvoidStaticFunctionPtr)();
    typedef ReturnValueT (GenericClass::*GenericMemFn)();
    typedef ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
    ClosureType m_closure;

public:


    // Construction and comparison functions
    FastDelegate0()
    {
        m_closure.clear();
    }

    FastDelegate0(const FastDelegate0 &x)
    {
        m_closure.CopyFrom(this, x.m_closure);
    }

    // Binding to non-const member functions
    template < class X, class Y >
    FastDelegate0(Y *pthis, DesiredReturnValueT (X::* function_to_bind)() )
    {
        m_closure.bindmemfunc(ImplicitCast<X*>(pthis), function_to_bind);
    }

    // Binding to const member functions.
    template < class X, class Y >
    FastDelegate0(const Y *pthis, DesiredReturnValueT (X::* function_to_bind)() const)
    {
        m_closure.bindconstmemfunc(ImplicitCast<const X*>(pthis), function_to_bind);
    }

    // Static functions. We convert them into a member function call.
    // This constructor also provides implicit conversion
    FastDelegate0(DesiredReturnValueT (*function_to_bind)() )
    {
        m_closure.bindstaticfunc(this, &FastDelegate0::InvokeStaticFunction, function_to_bind);
    }

private:    // Invoker for static functions

    ReturnValueT InvokeStaticFunction() const
    {
        return (*(m_closure.GetStaticFunction()))();
    }
};

//N=1
template<class Param1T, class ReturnValueT=DefaultVoid>
class FastDelegate1
{

public:

    typedef typename DefaultVoidToVoid<ReturnValueT>::type DesiredReturnValueT;
    typedef DesiredReturnValueT (*StaticFunctionPtr)(Param1T p1);
    typedef ReturnValueT (*UnvoidStaticFunctionPtr)(Param1T p1);
    typedef ReturnValueT (GenericClass::*GenericMemFn)(Param1T p1);
    typedef ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
    ClosureType m_closure;

public:


    // Construction and comparison functions
    FastDelegate1()
    {
        m_closure.clear();
    }

    FastDelegate1(const FastDelegate1 &x)
    {
        m_closure.CopyFrom(this, x.m_closure);
    }

    // Binding to non-const member functions
    template < class X, class Y >
    FastDelegate1(Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1) )
    {
        m_closure.bindmemfunc(ImplicitCast<X*>(pthis), function_to_bind);
    }

    // Binding to const member functions.
    template < class X, class Y >
    FastDelegate1(const Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1) const)
    {
        m_closure.bindconstmemfunc(ImplicitCast<const X*>(pthis), function_to_bind);
    }

    // Static functions. We convert them into a member function call.
    // This constructor also provides implicit conversion
    FastDelegate1(DesiredReturnValueT (*function_to_bind)(Param1T p1) )
    {
        m_closure.bindstaticfunc(this, &FastDelegate1::InvokeStaticFunction, function_to_bind);
    }

private:    // Invoker for static functions

    ReturnValueT InvokeStaticFunction(Param1T p1) const
    {
        return (*(m_closure.GetStaticFunction()))(p1);
    }
};

//N=2
template<class Param1T, class Param2T, class ReturnValueT=void>
class FastDelegate2
{

public:

    typedef typename DefaultVoidToVoid<ReturnValueT>::type DesiredReturnValueT;
    typedef DesiredReturnValueT (*StaticFunctionPtr)(Param1T p1, Param2T p2);
    typedef ReturnValueT (*UnvoidStaticFunctionPtr)(Param1T p1, Param2T p2);
    typedef ReturnValueT (GenericClass::*GenericMemFn)(Param1T p1, Param2T p2);
    typedef ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
    ClosureType m_closure;

public:

    // Construction and comparison functions
    FastDelegate2()
    {
        m_closure.clear();
    }

    FastDelegate2(const FastDelegate2 &x)
    {
        m_closure.CopyFrom(this, x.m_closure);
    }

    // Binding to non-const member functions
    template < class X, class Y >
    FastDelegate2(Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2) )
    {
        m_closure.bindmemfunc(ImplicitCast<X*>(pthis), function_to_bind);
    }

    // Binding to const member functions.
    template < class X, class Y >
    FastDelegate2(const Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2) const)
    {
        m_closure.bindconstmemfunc(ImplicitCast<const X*>(pthis), function_to_bind);
    }

    // Static functions. We convert them into a member function call.
    // This constructor also provides implicit conversion
    FastDelegate2(DesiredReturnValueT (*function_to_bind)(Param1T p1, Param2T p2) )
    {
        m_closure.bindstaticfunc(this, &FastDelegate2::InvokeStaticFunction, function_to_bind);
    }

private:    // Invoker for static functions

    ReturnValueT InvokeStaticFunction(Param1T p1, Param2T p2) const
    {
        return (*(m_closure.GetStaticFunction()))(p1, p2);
    }
};

//N=3
template<class Param1T, class Param2T, class Param3T, class ReturnValueT=DefaultVoid>
class FastDelegate3
{

public:

    typedef typename DefaultVoidToVoid<ReturnValueT>::type DesiredReturnValueT;
    typedef DesiredReturnValueT (*StaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3);
    typedef ReturnValueT (*UnvoidStaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3);
    typedef ReturnValueT (GenericClass::*GenericMemFn)(Param1T p1, Param2T p2, Param3T p3);
    typedef ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
    ClosureType m_closure;

public:

    // Construction and comparison functions
    FastDelegate3()
    {
        m_closure.clear();
    }

    FastDelegate3(const FastDelegate3 &x)
    {
        m_closure.CopyFrom(this, x.m_closure);
    }

    // Binding to non-const member functions
    template < class X, class Y >
    FastDelegate3(Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3) )
    {
        m_closure.bindmemfunc(ImplicitCast<X*>(pthis), function_to_bind);
    }

    // Binding to const member functions.
    template < class X, class Y >
    FastDelegate3(const Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3) const)
    {
        m_closure.bindconstmemfunc(ImplicitCast<const X*>(pthis), function_to_bind);
    }

    // Static functions. We convert them into a member function call.
    // This constructor also provides implicit conversion
    FastDelegate3(DesiredReturnValueT (*function_to_bind)(Param1T p1, Param2T p2, Param3T p3) )
    {
        m_closure.bindstaticfunc(this, &FastDelegate3::InvokeStaticFunction, function_to_bind);
    }

private:    // Invoker for static functions

    ReturnValueT InvokeStaticFunction(Param1T p1, Param2T p2, Param3T p3) const
    {
        return (*(m_closure.GetStaticFunction()))(p1, p2, p3);
    }
};

//N=4
template<class Param1T, class Param2T, class Param3T, class Param4T, class ReturnValueT=DefaultVoid>
class FastDelegate4
{

public:

    typedef typename DefaultVoidToVoid<ReturnValueT>::type DesiredReturnValueT;
    typedef DesiredReturnValueT (*StaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4);
    typedef ReturnValueT (*UnvoidStaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4);
    typedef ReturnValueT (GenericClass::*GenericMemFn)(Param1T p1, Param2T p2, Param3T p3, Param4T p4);
    typedef ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
    ClosureType m_closure;

public:

    // Construction and comparison functions
    FastDelegate4()
    {
        m_closure.clear();
    }

    FastDelegate4(const FastDelegate4 &x)
    {
        m_closure.CopyFrom(this, x.m_closure);
    }

    // Binding to non-const member functions
    template < class X, class Y >
    FastDelegate4(Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4) )
    {
        m_closure.bindmemfunc(ImplicitCast<X*>(pthis), function_to_bind);
    }

    // Binding to const member functions.
    template < class X, class Y >
    FastDelegate4(const Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4) const)
    {
        m_closure.bindconstmemfunc(ImplicitCast<const X*>(pthis), function_to_bind);
    }

    // Static functions. We convert them into a member function call.
    // This constructor also provides implicit conversion
    FastDelegate4(DesiredReturnValueT (*function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4) )
    {
        m_closure.bindstaticfunc(this, &FastDelegate4::InvokeStaticFunction, function_to_bind);
    }

private:    // Invoker for static functions

    ReturnValueT InvokeStaticFunction(Param1T p1, Param2T p2, Param3T p3, Param4T p4) const
    {
        return (*(m_closure.GetStaticFunction()))(p1, p2, p3, p4);
    }
};

//N=5
template<class Param1T, class Param2T, class Param3T, class Param4T, class Param5T, class ReturnValueT=DefaultVoid>
class FastDelegate5
{

public:

    typedef typename DefaultVoidToVoid<ReturnValueT>::type DesiredReturnValueT;
    typedef DesiredReturnValueT (*StaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5);
    typedef ReturnValueT (*UnvoidStaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5);
    typedef ReturnValueT (GenericClass::*GenericMemFn)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5);
    typedef ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
    ClosureType m_closure;

public:

    // Construction and comparison functions
    FastDelegate5()
    {
        m_closure.clear();
    }

    FastDelegate5(const FastDelegate5 &x)
    {
        m_closure.CopyFrom(this, x.m_closure);
    }

    // Binding to non-const member functions
    template < class X, class Y >
    FastDelegate5(Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5) )
    {
        m_closure.bindmemfunc(ImplicitCast<X*>(pthis), function_to_bind);
    }

    // Binding to const member functions.
    template < class X, class Y >
    FastDelegate5(const Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5) const)
    {
        m_closure.bindconstmemfunc(ImplicitCast<const X*>(pthis), function_to_bind);
    }

    // Static functions. We convert them into a member function call.
    // This constructor also provides implicit conversion
    FastDelegate5(DesiredReturnValueT (*function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5) )
    {
        m_closure.bindstaticfunc(this, &FastDelegate5::InvokeStaticFunction, function_to_bind);
    }

private:    // Invoker for static functions

    ReturnValueT InvokeStaticFunction(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5) const
    {
        return (*(m_closure.GetStaticFunction()))(p1, p2, p3, p4, p5);
    }
};

//N=6
template<class Param1T, class Param2T, class Param3T, class Param4T, class Param5T, class Param6T, class ReturnValueT=DefaultVoid>
class FastDelegate6
{

public:

    typedef typename DefaultVoidToVoid<ReturnValueT>::type DesiredReturnValueT;
    typedef DesiredReturnValueT (*StaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6);
    typedef ReturnValueT (*UnvoidStaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6);
    typedef ReturnValueT (GenericClass::*GenericMemFn)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6);
    typedef ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
    ClosureType m_closure;

public:

    // Construction and comparison functions
    FastDelegate6()
    {
        m_closure.clear();
    }

    FastDelegate6(const FastDelegate6 &x)
    {
        m_closure.CopyFrom(this, x.m_closure);
    }

    // Binding to non-const member functions
    template < class X, class Y >
    FastDelegate6(Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6) )
    {
        m_closure.bindmemfunc(ImplicitCast<X*>(pthis), function_to_bind);
    }

    // Binding to const member functions.
    template < class X, class Y >
    FastDelegate6(const Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6) const)
    {
        m_closure.bindconstmemfunc(ImplicitCast<const X*>(pthis), function_to_bind);
    }

    // Static functions. We convert them into a member function call.
    // This constructor also provides implicit conversion
    FastDelegate6(DesiredReturnValueT (*function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6) )
    {
        m_closure.bindstaticfunc(this, &FastDelegate6::InvokeStaticFunction, function_to_bind);
    }

private:    // Invoker for static functions

    ReturnValueT InvokeStaticFunction(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6) const
    {
        return (*(m_closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6);
    }
};

//N=7
template<class Param1T, class Param2T, class Param3T, class Param4T, class Param5T, class Param6T, class Param7T, class ReturnValueT=DefaultVoid>
class FastDelegate7
{

public:

    typedef typename DefaultVoidToVoid<ReturnValueT>::type DesiredReturnValueT;
    typedef DesiredReturnValueT (*StaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7);
    typedef ReturnValueT (*UnvoidStaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7);
    typedef ReturnValueT (GenericClass::*GenericMemFn)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7);
    typedef ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
    ClosureType m_closure;

public:

    // Construction and comparison functions
    FastDelegate7()
    {
        m_closure.clear();
    }

    FastDelegate7(const FastDelegate7 &x)
    {
        m_closure.CopyFrom(this, x.m_closure);
    }

    // Binding to non-const member functions
    template < class X, class Y >
    FastDelegate7(Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7) )
    {
        m_closure.bindmemfunc(ImplicitCast<X*>(pthis), function_to_bind);
    }

    // Binding to const member functions.
    template < class X, class Y >
    FastDelegate7(const Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7) const)
    {
        m_closure.bindconstmemfunc(ImplicitCast<const X*>(pthis), function_to_bind);
    }

    // Static functions. We convert them into a member function call.
    // This constructor also provides implicit conversion
    FastDelegate7(DesiredReturnValueT (*function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7) )
    {
        m_closure.bindstaticfunc(this, &FastDelegate7::InvokeStaticFunction, function_to_bind);
    }

private:    // Invoker for static functions

    ReturnValueT InvokeStaticFunction(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7) const
    {
        return (*(m_closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7);
    }
};

//N=8
template<class Param1T, class Param2T, class Param3T, class Param4T, class Param5T, class Param6T, class Param7T, class Param8T, class ReturnValueT=DefaultVoid>
class FastDelegate8
{

public:

    typedef typename DefaultVoidToVoid<ReturnValueT>::type DesiredReturnValueT;
    typedef DesiredReturnValueT (*StaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7, Param8T p8);
    typedef ReturnValueT (*UnvoidStaticFunctionPtr)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7, Param8T p8);
    typedef ReturnValueT (GenericClass::*GenericMemFn)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7, Param8T p8);
    typedef ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
    ClosureType m_closure;

public:

    // Construction and comparison functions
    FastDelegate8()
    {
        m_closure.clear();
    }

    FastDelegate8(const FastDelegate8 &x)
    {
        m_closure.CopyFrom(this, x.m_closure);
    }

    // Binding to non-const member functions
    template < class X, class Y >
    FastDelegate8(Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7, Param8T p8) )
    {
        m_closure.bindmemfunc(ImplicitCast<X*>(pthis), function_to_bind);
    }

    // Binding to const member functions.
    template < class X, class Y >
    FastDelegate8(const Y *pthis, DesiredReturnValueT (X::* function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7, Param8T p8) const)
    {
        m_closure.bindconstmemfunc(ImplicitCast<const X*>(pthis), function_to_bind);
    }

    // Static functions. We convert them into a member function call.
    // This constructor also provides implicit conversion
    FastDelegate8(DesiredReturnValueT (*function_to_bind)(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7, Param8T p8) )
    {
        m_closure.bindstaticfunc(this, &FastDelegate8::InvokeStaticFunction, function_to_bind);
    }

private:    // Invoker for static functions

    ReturnValueT InvokeStaticFunction(Param1T p1, Param2T p2, Param3T p3, Param4T p4, Param5T p5, Param6T p6, Param7T p7, Param8T p8) const
    {
        return (*(m_closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8);
    }

};


} //namespace Internals
} //namespace Common
} //namespace QuimeraEngine
} //namespace Kinesis

#endif // __DELEGATEINTERNALS__
